package eerbaar.shared.persist.internal.lib;

import java.util.List;

import eerbaar.level.IActions;
import eerbaar.level.IExpressions;
import eerbaar.level.IState;
import eerbaar.level.LevelFactory;
import eerbaar.shared.exceptions.GameException;
import eerbaar.shared.exceptions.GameRuntimeException;
import eerbaar.shared.persist.IPersistService;
import eerbaar.shared.persist.IPersister;
import eerbaar.shared.persist.ISaver;
import eerbaar.shared.service.ServiceFactory;
import eerbaar.shared.tree.IAttributes;
import eerbaar.shared.tree.INode;
import eerbaar.shared.tree.NodeCmdFactory;

public class StatePersister implements IPersister<IState> {

    public static final String NAME = "state";

    private IState target;

    public StatePersister() {
        //
    }

    public StatePersister(INode node) throws GameRuntimeException {
        load(node);
    }

    public StatePersister(IState wrapper) {
        this.target = wrapper;
    }

    @Override
    public Class<IState> getRegistertedInterface() {
        return IState.class;
    }

    @Override
    public ISaver<?>[] getSavableChildren() {

        ExpressionsPersister e = new ExpressionsPersister(
                this.target.getExpressions());
        ActionsPersister a = new ActionsPersister(this.target.getActions());
        return new ISaver<?>[] { a, e };
    }

    @Override
    public String getSavableName() {

        return NAME;
    }

    @Override
    public IState getTarget() {
        return this.target;
    }

    @Override
    public boolean isAssignableFrom(ISaver<?> savable) {
        return false;
    }

    @Override
    public IState load(INode node) {
        assert (node != null);

        IState result = LevelFactory.createState();

        IPersistService service = ServiceFactory
                .getService(IPersistService.class);

        IAttributes attributes = node.getAttributes();
        int priority = attributes.get(Integer.class, "priority");
        result.setPriority(priority);

        {
            List<INode> list = NodeCmdFactory.findChildren(node,
                    ActionsPersister.NAME);
            for (INode n : list) {
                try {
                    IActions actions = service.load(IActions.class, n);
                    result.setActions(actions);
                } catch (GameException e) {
                    e.printStackTrace();
                }
            }
        }
        {
            List<INode> list = NodeCmdFactory.findChildren(node,
                    ExpressionsPersister.NAME);
            for (INode n : list) {
                try {
                    IExpressions expressions = service.load(IExpressions.class,
                            n);
                    result.setExpressions(expressions);
                } catch (GameException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    @Override
    public void saveAttributes(INode node) {

        IAttributes a = node.getAttributes();
        a.set(Integer.class, "priority", this.target.getPriority());
    }

    @Override
    public void setTarget(IState obj) {
        this.target = obj;
    }

}
